package com.cyq.dascma.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.cyq.dascma.constant.ImportType;
import com.cyq.dascma.dto.ScoreInfoDto;
import com.cyq.dascma.entity.Score;
import com.cyq.dascma.entity.Student;
import com.cyq.dascma.entity.Teacher;
import com.cyq.dascma.result.Result;
import com.cyq.dascma.result.ResultGenerator;
import com.cyq.dascma.service.ScoreService;
import com.cyq.dascma.service.StudentService;
import com.cyq.dascma.service.TeacherService;
import com.cyq.dascma.util.DateTimeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Excel 操作综合控制器
 *
 * @author Administrator
 * 2021.03.26 15:41
 */
@Api(tags = "Excel 操作模块")
@RestController
@RequestMapping("/excel")
public class ExcelController {
    private final StudentService studentService;
    private final TeacherService teacherService;
    private final ScoreService scoreService;

    @Autowired
    ExcelController(StudentService studentService,
                    ScoreService scoreService,
                    TeacherService teacherService) {
        this.studentService = studentService;
        this.teacherService = teacherService;
        this.scoreService = scoreService;
    }

    @ApiOperation(value = "批量Excel入库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "multipartFile", value = "文件流对象", required = true, dataType = "MultipartFile"),
            @ApiImplicitParam(name = "importType", value = "导入的类型", required = true, dataType = "String")
    })

    @PostMapping("/import")
    public Result uploadStudents(@RequestParam("file") MultipartFile multipartFile, @RequestParam("importType") ImportType importType) {
        boolean executeResult = false;
        // 获取文件存储相对路径
        String storePath = System.getProperty("user.dir") + "/src/main/resources/static/excel/";
        // 获取文件名称
        String fileName = multipartFile.getOriginalFilename();
        // 判断目录是否存在，没有则创建
        assert fileName != null;
        File file = new File(storePath, fileName);
        if (!file.getParentFile().exists()) {
            boolean mkdirs = file.getParentFile().mkdirs();
        }
        // 上传
        try {
            multipartFile.transferTo(file);
            String fullPath = storePath + fileName;

            switch (importType) {
                case STUDENT:
                    // 导入学生信息
                    executeResult = importStudents(fullPath);
                    break;
                case TEACHER:
                    executeResult = importTeachers(fullPath);
                    break;
                case SCORE:
                    executeResult = importScores(fullPath);

            }

            return ResultGenerator.genOkResult(executeResult);
        } catch (IOException e) {
            e.printStackTrace();
            return ResultGenerator.genFailureResult("文件上传失败");
        }
    }

    /*
     * 导入学生信息
     * @param file
     * @return Student>
     */
    public boolean importStudents(String fullPath) {

        ExcelReader reader = ExcelUtil.getReader(fullPath);
        List<Student> studentList = reader.readAll(Student.class);
        return studentService.saveBatch(studentList);
    }

    /*
     * 导入成绩计算所属数据
     * @param file
     * @return Score>
     */
    public boolean importScores(String fullPath) {

        ExcelReader reader = ExcelUtil.getReader(fullPath);
        List<Score> scoreList = reader.readAll(Score.class);
        return scoreService.saveBatch(scoreList);
    }

    /*
     * 导入教师信息
     * @param file
     * @return Student>
     */
    public boolean importTeachers(String fullPath) {
        ExcelReader reader = ExcelUtil.getReader(fullPath);
        List<Teacher> teacherList = reader.readAll(Teacher.class);
        return teacherService.saveBatch(teacherList);
    }

    @ApiOperation("导出成绩数据到Excel")
    @GetMapping("/export")
    public void export(HttpServletResponse response) {
        Map<String, Object> params = new HashMap<>();
        params.put("offset", 1);
        params.put("limit", scoreService.count());
        List<ScoreInfoDto> scoreInfoDtoList = scoreService.findScoreInfoList(params);
        scoreInfoDtoList.stream().sequential().forEach(scoreInfoDto -> {
            if (scoreInfoDto.getCourseType() == 0) {
                scoreInfoDto.setCourseTypeStr("专业必修");
            } else {
                scoreInfoDto.setCourseTypeStr("专业选修");
            }
        });
        List<ScoreInfoDto> rows = CollUtil.newArrayList(scoreInfoDtoList);

        // 通过工具类创建writer，默认创建xls格式
        ExcelWriter writer = ExcelUtil.getWriter();
        writer.merge(13, "成绩单");


        //自定义标题别名
        writer.addHeaderAlias("scoreId", "成绩编号");
        writer.addHeaderAlias("courseName", "课程名称");
        writer.addHeaderAlias("courseTypeStr", "课程类型");
        writer.addHeaderAlias("courseType", "课程类型代码");
        writer.addHeaderAlias("clazzName", "班级名称");
        writer.addHeaderAlias("studentName", "学生姓名");
        writer.addHeaderAlias("studentId", "学号");
        writer.addHeaderAlias("courseId", "课程代码");
        writer.addHeaderAlias("scoreAttendance", "考勤成绩");
        writer.addHeaderAlias("scoreClazz", "平时上课成绩");
        writer.addHeaderAlias("scoreHomework", "作业成绩");
        writer.addHeaderAlias("scoreMiddle", "期中成绩");
        writer.addHeaderAlias("scoreEnd", "期末成绩");
        writer.addHeaderAlias("scoreFinal", "最终成绩");

        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(rows, true);

        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename="+ DateTimeUtil.getSysTime() +".xls");
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        writer.flush(out, true);
        // 关闭writer，释放内存
        writer.close();
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }
}
